

package javaapplication6;
import java.net.URL;
import java.util.ArrayList;
import java.util.Observable;

public abstract class Dowloader extends Observable implements Runnable{

        protected URL mURL; // URL для загрузки файла
	protected String mOutputFolder; //папка для загрузки файла
	protected int mNumConnections; //кол-во потоков для закачки
        protected String mFileName; //Имя загружаемого файла
	protected int mFileSize; //Размер загружаемого файла
        protected int mState; //Состояние загрузки
        protected int mDownloaded; // Размер загруженной части файла
        protected  static  boolean mproxyRequired;
        protected  static  String mproxyIP;
        protected  static  String mproxyPort;
        protected  static  String mproxyUsername;
        protected  static  String mproxyPassword;
        // Список потоков загрузки
        protected ArrayList<DownloadThread> mListDownloadThread;
	protected static final int BLOCK_SIZE = 2048; // Размер блока загрузки
	protected static final int BUFFER_SIZE = 2048;// Размер буфера
        //Минимальный размер загружаемого файла
	protected static final int MIN_DOWNLOAD_SIZE = BLOCK_SIZE * 100;
        // Статусы загрузки
        public static final String STATUSES[] = {"Загрузка","Пауза",
        "Файл загружен", "Отменено", "Ошибка"};
        // Числовые значения статусов
	public static final int DOWNLOADING = 0;
	public static final int PAUSED = 1;
	public static final int COMPLETED = 2;
	public static final int CANCELLED = 3;
	public static final int ERROR = 4;

        // Конструктор класса Dowloader
	protected Dowloader(URL url, String outputFolder, int numConnections,ProxySettings PS) {
		mURL = url;
		mOutputFolder = outputFolder;
		mNumConnections = numConnections;
                mproxyRequired = PS.getProx();
                mproxyIP = PS.getProxyIp();
                mproxyPort = PS.getPortNum();
                mproxyUsername = PS.getUserName();
                mproxyPassword = PS.getPass();
                // Получение пути к файлу
		String fileURL = url.getFile();
		mFileName = fileURL.substring(fileURL.lastIndexOf('/') + 1);
		System.out.println("File name: " + mFileName);
		mFileSize = -1; // Начальный размер файла
		mState = DOWNLOADING; // Начальный статус загрузки
		mDownloaded = 0; // Начальный размер загруженной части
        // Список потоков загрузки
		mListDownloadThread = new ArrayList<DownloadThread>();
	}

// Функция приостановки загрузки
	public void pause() {
		setState(PAUSED);
	}

// Функция возобновления загрузки
	public void resume() {
		setState(DOWNLOADING);
		download();
	}

// Функция отмены загрузки файла
	public void cancel() {
		setState(CANCELLED);
	}

// Функция получения адреса файла
	public String getURL() {
		return mURL.toString();
	}

// Функция получения размера файла
	public int getFileSize() {
		return mFileSize;
	}

// Функция получения прогресса загрузки
	public float getProgress() {
		return ((float)mDownloaded / mFileSize) * 100;
	}

// Функция получения статуса загрузки
	public int getState() {
		return mState;
	}

// Функция установки статуса загрузки
	protected void setState(int value) {
		mState = value;
		stateChanged();
	}

// Функция загрузки файла
	protected void download() {
		Thread t = new Thread(this);
		t.start();
	}

// Функция увеличения загруженной части файла
	protected synchronized void downloaded(int value) {
		mDownloaded += value;
		stateChanged();
	}

// Функция оповещения обозревателей об изменении состояния загрузки
	protected void stateChanged() {
		setChanged();
		notifyObservers();
	}

// Класс потока для загрузки
	protected abstract class DownloadThread implements Runnable {
		protected int mThreadID;
		protected URL mURL;
		protected String mOutputFile;
		protected int mStartByte;
		protected int mEndByte;
		protected boolean mIsFinished;
		protected Thread mThread;
// Конструктор класса DownloadThread
		public  DownloadThread(int threadID, URL url, String outputFile, int startByte, int endByte) {
			mThreadID = threadID;
			mURL = url;
			mOutputFile = outputFile;
			mStartByte = startByte;
			mEndByte = endByte;
			mIsFinished = false;
			download();
		}

// Функция проверки загрузки части файла
		public boolean isFinished() {
			return mIsFinished;
		}

// Функция загрузки файла
		public   void   download() {
			mThread = new Thread(this);
			mThread.start();

		}

// Функция ожидания окончания загрузки
		public   void waitFinish() throws InterruptedException {
			mThread.join();
		}

	}
}
